/* 
 * dnsServer.h :
 */


//DNS MSG structure --RFC 1035

/*
 * DNS header:
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      ID                       |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    QDCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ANCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    NSCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ARCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

*/
/*
 *Question section format:
                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                     QNAME                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     QTYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     QCLASS                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

*/
/*
 *Resource record format
   answer, authority, and additional:

                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                                               /
    /                      NAME                     /
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     CLASS                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TTL                      |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                   RDLENGTH                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
    /                     RDATA                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/


#ifndef __DNS_HEADER__
#define __DNS_HEADER__
#pragma pack(push, 1)
struct FLAG
{
  unsigned char qr :1; /* query/response flag*/
  unsigned char opcode :4; /* purpose of message*/
  unsigned char aa :1; /* authoritive answer*/
  unsigned char tc :1; /* truncated message*/
  unsigned char rd :1; /* recursion desired*/
  unsigned char ra :1; /* recursion available*/
  unsigned char z :1; /* its z! reserved*/
  unsigned char ad :1; /* authenticated data*/
  unsigned char cd :1; /* checking disabled*/ 
  unsigned char rcode :4; /* response code*/
 
};
struct DNS_HEADER
{
unsigned short id; /* identification number*/

//unsigned char qr :1; /* query/response flag*/
//unsigned char opcode :4; /* purpose of message*/
//unsigned char aa :1; /* authoritive answer*/
//unsigned char tc :1; /* truncated message*/
//unsigned char rd :1; /* recursion desired*/
//unsigned char ra :1; /* recursion available*/
//unsigned char z :1; /* its z! reserved*/
//unsigned char ad :1; /* authenticated data*/
//unsigned char cd :1; /* checking disabled*/

//unsigned char rcode :4; /* response code*/
//struct FLAG flag;
unsigned short flag;


unsigned short q_count; /* number of question entries*/
unsigned short ans_count; /* number of answer entries*/
unsigned short auth_count; /* number of authority entries*/
unsigned short add_count; /* number of resource entries*/
};

/*Constant sized fields of query structure*/
struct QUESTION
{
	unsigned short qtype;
	unsigned short qclass;
};
/*Structure of a Query*/
struct QUERY
{
	unsigned char *name;
	struct QUESTION *ques;
};
/*
struct RECV
{
    struct DNS_HEADER *header;
    QUERY query;
};
*/

/*Constant sized fields of the resource record structure*/
       /*answer, authority, and additional*/
struct R_DATA
{
	unsigned short type;
	unsigned short _class;
	unsigned int ttl;
	unsigned short data_len;
};
/*Pointers to resource record contents*/
struct RES_RECORD
{
	unsigned char *name;
	struct R_DATA *resource;
	unsigned char *rdata;
};
#pragma pack(pop)

/*
 * struct sockaddr_in {
 *     short int si_family;
 *     unsigned short in sin_port;
 *     struct in_addr sin_addr;
 * }
 * struct in_addr{
 *     unsigned long int s_addr;
 * }
 *
 * */

/* cover www.stu.edu.cn to 3www2stu3edu2cn0 */
void change2dnsNameFormat(unsigned char* dnsName, unsigned char* host);

/* get location according to ip address */
int getLocation(char *ipaddr, char *localtion);

/* cover 3www2stu3edu2cn0 to www.stu.edu.cn */
unsigned char* readName(unsigned char *dnsName);

/* get the domain A record. by abs(step) */
int getArecord(unsigned char* urlName, char *localtion, char *record);

/* according the local DNS server location to get the A record location.*/
int getDistanceKey(char *dis_file, char *localtion, char *dis_key);

/* get the domain A record by rule--from the distance.db file. */
int getArecord2(unsigned char* urlName, char *localtion, char *record);

/* print the usage of this program. */
void print_usage (FILE* stream, int exit_code);

/* parse the argv option, main job is set file database directory. */
void parse_opt (int argc, char** argv);

/* check the database directory and the dns ip list file whether exist.*/
void check_file_exit(void);

/* update the domain config files by every hours --this FN only get domain files*/
void update_config_files(void);

/* check the domain file is updateable and do updata*/
void check_and_update(char *domain_file);
#endif
